<?php
/**
 * 菜单数据模型
 *
 * PHP version 5
 *
 * @package   SS
 * @author    Fee <Fee@shorigo.com>
 * @copyright 2015 SRG Inc.
 */
namespace Admin\Model;
use Think\Model;
class MenusModel extends Model {

   protected $tableName = 'sys_menus'; 
   
    /**
     * 设置主键
     *
     * @author Fee
     */
    protected $pk        = 'menu_id';

    /**
     * 自动验证
     *
     * @author Fee
     */
    protected $_validate = array(
        array('menu_title',   'require', '名称不能为空'),
     );

    /**
     * 自动完成
     *
     * @author Fee
     */
    protected $_auto     = array(
            array('menu_title', 'remove_xss', 3, 'function'),
            array('controller', 'remove_xss', 3, 'function'),
            array('action', 'remove_xss', 3, 'function'),
            array('parentPath', 'getParentPath', 3, 'callback'),
            array('explain', 'remove_xss', 3, 'function'),
        );

   /**
     * 返回所有分类（排好序的）
     *
     *
     * @return array    menu_id
     *                  parent_id
     *                  menu_title
     *                  layer   层次
     *                  isLeaf  是否叶子结点
     * @author Fee
     */
    public function fetchAll()
    {
        static $data = null;
        if (is_null($data)) {
            import("Com.Tree.Tree");
            $tree = new \Org\Util\Tree;

            $columns = $this->field('menu_id,parent_id,menu_title,explain,sortNum,controller,action')
                            ->order('sortNum asc, menu_id desc')
                            ->select();
            foreach ($columns as $key => $cate) {
                $tree->setNode($cate['menu_id'], $cate['parent_id'], $key);
            }
            $sortedNodes = $tree->getSortedNodes();

            $data = array();
            foreach ($sortedNodes as $node) {
                $cates = $columns[$node['data']];
                $cates['layer']  = $node['layer'];
                $cates['isLeaf'] = $node['isLeaf'];
                $data[] = $cates;
            }
        }
        return $data;
    }

    /**
     * 取得记录的父路径
     *
     * @return string parentPath
     * @author Fee
     */
    protected function getParentPath() {
        $parentid     = $_POST['parent_id'];
        $parent = $this->field("parentPath")->find($parentid);
        $parentPath   = $parent["parentPath"];
        if ($parentPath != "") {
            $path = $parentPath . $parentid . "/";
        } else {
            $path = "/0/";
        }
        return $path;
    }

    /**
     * 获取父级菜单下所有子菜单id列表
     *
     * @return array $array
     * @author Fee
     */
    public function getIdsByPid($pid) {
        $colimn = $this->where('parentPath like "%/' . $pid .'/%"')
            ->field('menu_id')->select();
        $array = array();
        $array[] = $pid;
        foreach ($colimn as $c) {
            $array[] = $c['menu_id'];
        }
        return $array;
    }

    /**
     * 取得用于生成select的options的数组
     *
     * @return array
     * @author Fee
     */
    public function getOptions() {
        $options = array();
        $space = str_repeat('-', 4);
        
        $groups = $this->fetchAll();

        foreach ($groups as $group) {
           $options[$group['menu_id']] = str_repeat($space, $group['layer'] - 1) . ' ' . $group['menu_title'];
        }
        return $options;
    }

    /**
     * 得到树状结构
     *
     * @param int $parent_id 父分类ID
     *
     * @return array  array('data' => ?, 'children' => array('data' => ?, 'children' => array())),
     *                array('data' => ?, 'children' => array('data' => ?, 'children' => array())),
     *                ...
     * @author Fee
     */
    public static function getTree($parent_id = 0)
    {
        $tree = new \Org\Util\Tree;

        $conditions = '';
        $map = array();
        if ($parent_id > 0) {
            $map['parentPath'] = array('like', "%/" . $parent_id . "/%");
        }
        $Menus = D("Menus");
        $productCates = $Menus->where($map)
                              ->field('menu_id,parent_id,menu_title,controller,action,sortNum')
                              ->order('sortNum asc,menu_id desc')
                              ->select();

        foreach ($productCates as $key => $cate) {
            $tree->setNode($cate['menu_id'], $cate['parent_id'], $cate);
        }

        $tree->rootId = $parent_id;

        $sortedNodesArr = $tree->getSortedNodes();
        $treeArr = array();

        $nodesLevelRef = array(array('ref' => &$treeArr, 'index' => 0));
        foreach ($sortedNodesArr as $k => $v) {
            $level = $v['layer'];
            $node = array_merge($v['data'], array('layer' => $level));
            $node['children'] = array();

            $nodesLevelRef[$level - 1]['ref'][$nodesLevelRef[$level - 1]['index']] =  $node;
            if (isset($sortedNodesArr[$k + 1]) && $sortedNodesArr[$k + 1]['layer'] > $level) {
                $nodesLevelRef[$level] = array(
                    'ref'   => &$nodesLevelRef[$level - 1]['ref'][$nodesLevelRef[$level - 1]['index']]['children'],
                    'index' => 0
                );
            }
            $nodesLevelRef[$level - 1]['index']++;
        }
        return $treeArr;
    }

    /**
     * 取得菜单数据
     *
     * @return array
     * @author Fee
     */
    public function getOrder() {
        $menus = $this->getTree();
        $Auths = D("Auths");
        $auth = $Auths->getAdminAuths();
        $menu_list = $this->checkPrivilege($menus, $auth);
        return $menu_list;
    }

    /**
     * 递归检测权限
     *
     * @return array
     * @author Fee
     */
    function checkPrivilege($menus,$auth) {
        foreach($menus as $key => $menu) {
            $check = isset($auth[$menu['controller']]) && in_array($menu['action'], $auth[$menu['controller']]);
            if(!$check){
                unset($menus[$key]);
            } else {
                if(!empty($menu['children'])) {
                    $menus[$key]['children'] = $this->checkPrivilege($menu['children'], $auth);
                }
            }
        }
        return $menus;
    }

}
?>